package com.demo.webapp.servlet;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.demo.core.model.File;
import com.demo.core.service.DocumentService;
import com.demo.webapp.servlet.DownloadServlet.FileInfo;

/**
 * 图片文件下载Servlet
 * 依赖于Spring容器和CORE包
 * @author ryuu.kk
 *
 */
public class ImageDownloadServlet extends DownloadServlet {

	/**
	 * 版本序列化ID
	 */
	private static final long serialVersionUID = -7955042153801484409L;
	
	/**
	 * Spring容器上下文
	 */
	protected ApplicationContext applicationContext;
	
	/**
	 * 文档管理服务
	 */
	private static String DOCUMENT_BEAN_NAME = "documentService";
	
	/**
	 * 文档服务
	 */
	private DocumentService documentService;
	
	/**
	 * Servlet
	 */
	private ServletConfig config;
	
	public void init(ServletConfig config) throws ServletException {
		this.config = config;
		super.init(config);
		//取得spring上下文
		applicationContext = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
	}

	/**
	 * 重写前置处理方法
	 * 使用图片在当前页面中显示而不是下载
	 */
	protected boolean preDownload(HttpServletRequest request, HttpServletResponse response, FileInfo fileInfo) throws UnsupportedEncodingException {

		//取得文件名
		String fileName = fileInfo.getFileName();
		//文件类型
		String contentType = fileInfo.getContentType();
		long size;
		String agent = (String) request.getHeader("USER-AGENT");  
    	if (agent != null && agent.indexOf("MSIE") > 0) {
    		fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
    	} else {
    		fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
    	}
    	size = fileInfo.getSize();
		//设置响应头
    	response.setHeader("Cache-Control", "max-age=86400");
        response.setHeader("Content-Length", String.valueOf(size));
    	//response.setContentType(contentType);
    	//response.setHeader("Pragma", "no-cache");
    	//response.setHeader("cache-control", "no-cache");
    	//response.setHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT");
		//response.setHeader("Content-Disposition", "inline; filename=" + fileName);
    	//response.setContentType("image/jpg");
    	response.setHeader("Content-Type","image/" + contentType.toLowerCase());  
		return true;
	}
	@Override
	protected InputStream getFileInputStream(FileInfo fileInfo) throws ServletException {

		// 在临时文件夹下创建
		String imagePath = getTmpPath() + "/" +fileInfo.getUuid() + "." +fileInfo.getContentType();
		InputStream in = null;
		BufferedOutputStream out = null;
		try {
			in = new FileInputStream(new java.io.File(imagePath));
		} catch (FileNotFoundException e) {
			//throw new ServletException(e);
		}
		if (in != null) {
			return in;
		}
		
		in = documentService.queryFileStream(fileInfo.getFileId());
		
		try {
			// 本地化图片文件
			out = new BufferedOutputStream(new FileOutputStream(imagePath));
			IOUtils.copy(in, out);
		} catch (IOException e) {
			e.printStackTrace();
			return in;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					// nothing
				}
			}
			if (out != null) {
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
					// nothing
				}
			}
		}
		// return config.getServletContext().getResourceAsStream(imagePath);
		return getFileInputStream(fileInfo);
	}
	
	@Override
	protected FileInfo getFileInfo(HttpServletRequest request) throws FileNotFoundException {
		
		//String uuid = request.getParameter("uuid");
		String uuid = request.getPathInfo().substring(1);
		int index = request.getPathInfo().lastIndexOf(".");
		if (index != -1) {
			// 有扩展名则去掉
			uuid = uuid.substring(0, index - 1);
		}
		Long fileId = null;
		String fileName = null;
		String path = null;
		String contentType = null;
		long size = 0L;
		if (StringUtils.isBlank(uuid)) {
			throw new FileNotFoundException("uuid is empty.");
		}
		
		if (documentService == null) {
			documentService = applicationContext.getBean(DOCUMENT_BEAN_NAME, DocumentService.class);
		}
		
		//id为空或文件不存在,则抛出异常
		if (StringUtils.isBlank(uuid) || !documentService.fileExists(uuid)) {
			throw new FileNotFoundException("uuid is empty. or UUID:" + uuid + " not found.");
		}
		
		//取得文件对象,但不取得文件内容
		File file = documentService.findFile(uuid, false);
		
		if (file.isEnabled()) {
			//文件不可用
		}
		
		fileId = file.getId();
		fileName = file.getName();
		contentType = file.getContentType();
		// contentType = "image/*";
		size = file.getSize();
		path = file.getPath();
		//FileNotFoundException
		return new FileInfo(fileId, uuid, fileName, path, contentType, (int)size);
	}
}
